package cz.muni.fi.pa165.sportclubmanager.service;

import cz.muni.fi.pa165.sportclubmanager.dao.AgeCategoryDAO;
import cz.muni.fi.pa165.sportclubmanager.dto.AgeCategoryDTO;
import cz.muni.fi.pa165.sportclubmanager.dto.AgeCategoryDTOMapping;
import cz.muni.fi.pa165.sportclubmanager.entity.AgeCategory;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.jws.WebService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Matus Duchon (xduchon2@fi.muni.cz, 418127)
 */
@Service
@WebService(endpointInterface = "cz.muni.fi.pa165.sportclubmanager.service.AgeCategoryService", serviceName="AgeCategoryWebService")
public class AgeCategoryServiceImpl implements AgeCategoryService {

    private AgeCategoryDAO ageCategoryDAO;

    @Autowired
    public void setAgeCategoryDAO(AgeCategoryDAO ageCategoryDAO) {
        this.ageCategoryDAO = ageCategoryDAO;
    }

    @Override
    @Transactional
    @Secured({"ROLE_ADMIN"})
    public void create(AgeCategoryDTO ac) {
        // check if ac not overlaps other existing category
        checkOverlapping(ac);
        // otherwise creates it
        ageCategoryDAO.create(AgeCategoryDTOMapping.toEntity(ac));
    }

    @Override
    @Transactional
    @Secured("ROLE_ADMIN")
    public void update(AgeCategoryDTO ac) {
        // check if ac not overlaps other existing category
        checkOverlapping(ac);
        // otherwise updates it
        ageCategoryDAO.update(AgeCategoryDTOMapping.toEntity(ac));
    }

    @Override
    @Transactional
    @Secured("ROLE_ADMIN")    
    public void remove(AgeCategoryDTO ac) {
        ageCategoryDAO.remove(AgeCategoryDTOMapping.toEntity(ac));
    }

    @Override
    @Transactional
    @Secured({"ROLE_USER","ROLE_ADMIN"})    
    public AgeCategoryDTO find(Long id) {
        return AgeCategoryDTOMapping.toDto(ageCategoryDAO.find(id));
    }

    @Override
    @Transactional
    @Secured({"ROLE_USER","ROLE_ADMIN"})        
    public List<AgeCategoryDTO> findAll() {
        List<AgeCategory> list = ageCategoryDAO.findAll();
        List<AgeCategoryDTO> dtoList = new ArrayList<AgeCategoryDTO>();

        for (Iterator i = list.iterator(); i.hasNext();) {
            dtoList.add(AgeCategoryDTOMapping.toDto((AgeCategory) i.next()));
        }

        return dtoList;
    }

    private void checkOverlapping(AgeCategoryDTO ac) {
        // get all age categories
        List<AgeCategory> findAll = ageCategoryDAO.findAll();

        // check that the new one is not in conflict with them
        for (AgeCategory ac2 : findAll) {
           // System.out.println(ac2 + "\n" + AgeCategoryDTOMapping.toEntity(ac) + "\n==========================");

            // if it is the same age category, skip it (to be able to update)
            if (ac2.equals(AgeCategoryDTOMapping.toEntity(ac))) {
                continue;
            }

            // if it overlaps age category under -> fail, or
            // if it overlaps age category above -> fail, or
            // if it overlaps entire age category -> fail
            if ((ac2.getAgeFrom() <= ac.getAgeFrom() && ac.getAgeFrom() <= ac2.getAgeTo())
                    || (ac2.getAgeFrom() <= ac.getAgeTo() && ac.getAgeTo() <= ac2.getAgeTo())
                    || (ac.getAgeFrom() <= ac2.getAgeFrom() && ac2.getAgeTo() <= ac.getAgeTo())) {
                throw new IllegalArgumentException("Age category bounds overlap to some other existing age category:"
                        + " existing " + ac2
                        + "; current " + AgeCategoryDTOMapping.toEntity(ac));
            }
        }
    }
}
